﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using MvcFileUploader;
using MvcFileUploader.Models;
using PhotoBlog.Core.Helpers;
using PhotoBlog.Core.Models;
using PhotoBlog.Core.Models.Albums;
using PhotoBlog.Core.Models.Photos;
using PhotoBlog.Models.ClientModels;

namespace PhotoBlog.Models.Photos
{
    public class PhotoService : IPhotoService
    {
        private const string UploadPath = "UploadedFiles/";
        private static readonly string StorageRoot = AppDomain.CurrentDomain.BaseDirectory + UploadPath;
        private readonly IPhotoRepository photoRepository;
        private readonly IAlbumRepository albumRepository;

        public PhotoService(IPhotoRepository photoRepository, IAlbumRepository albumRepository)
        {
            this.photoRepository = photoRepository;
            this.albumRepository = albumRepository;
        }

        public void SaveImages(FileUploadVm fileUploadVm)
        {
            foreach (var file in fileUploadVm.UploadedFiles.Where(file => file != null))
            {
                SaveImageFile(file, fileUploadVm.Login, fileUploadVm.AlbumId);
            }
            var httpFileCollectionBase = fileUploadVm.UploadedRequestFiles;
            if (httpFileCollectionBase == null) return;
            for (var i = 0; i < httpFileCollectionBase.Count; i++)
            {
                SaveImageFile(httpFileCollectionBase[i], fileUploadVm.Login, fileUploadVm.AlbumId);
            }
        }

        public void DeleteImage(string login, int id)
        {
            var album = albumRepository.FindByImageId(id);
            if (album != null)
            {
                var pathDisc = BuildPath(login, string.Format("album-{0}", album.AlbumId), id);
                if (Directory.Exists(pathDisc))
                {
                    Directory.Delete(pathDisc, recursive: true);
                }
                photoRepository.Delete(id);
            }
        }

        public List<ViewDataUploadFileResult> SaveImageFiles(FileUploadVm model)
        {
            var statuses = new List<ViewDataUploadFileResult>();
            for (var i = 0; i < model.UploadedRequestFiles.Count; i++)
            {
                var st = SaveImageFile(model.UploadedRequestFiles[i], model.Login, model.AlbumId);
                statuses.Add(st);
            }
            return statuses;
        }


        private Photo SaveImageDb(HttpPostedFileBase file, int albumId, string path, string fileName)
        {
            var photo = new Photo
            {
                AlbumId = albumId,
                Path = path.Replace('\\', '/'),
                Extention = file.ContentType,
                PhotoName = fileName,
                Date = DateTime.Now,
                Description = "",
                Music = ""
            };
            return photoRepository.Add(photo);
        }

        private static string BuildPath(string login, string albumPath, int imgId)
        {
            var fullPath = Path.Combine(StorageRoot, login, albumPath, imgId.ToString()).Replace('\\', '/');
            return fullPath;
        }

        private static string BuildWebPath(string login, string albumPath)
        {
            var path = string.Format("{0}/", Path.Combine(UploadPath, login, albumPath));
            return path;
        }

        public static void CreateDirectory(string path)
        {
            Directory.CreateDirectory(path);
        }

        public ViewDataUploadFileResult SaveImageFile(HttpPostedFileBase file, string login, int albumId)
        {
            var checkContentType = CheckContentType(file);
            if (checkContentType)
            {
                var filename = Path.GetFileName(file.FileName);
                if (filename != null)
                {
                    filename = filename.ToLower();
                    var albumPath = string.Format("album-{0}", albumId);
                    var pathWeb = BuildWebPath(login, albumPath);
                    var savedPhoto = SaveImageDb(file, albumId, pathWeb, filename);
                    if (savedPhoto != null)
                    {
                        var pathDisc = BuildPath(login, albumPath, savedPhoto.PhotoId);
                        SavePhotoInFolder(file, pathDisc, filename, 1400, 1000);
                        SavePhotoInFolder(file, pathDisc + "/T", filename, 466, 333);

                        var fullPath = string.Format("{0}/{1}", pathDisc, filename);
                        var thumbnailUrl = string.Format("\\{0}{1}/{2}", pathWeb, savedPhoto.PhotoId, filename);
                        return BuildUploadFileResult(file, fullPath, thumbnailUrl);
                    };

                }
            }
            return new ViewDataUploadFileResult
            {
                error = "Файл должен быть типа: jpeg, png, gif"
            };
        }

        private static bool CheckContentType(HttpPostedFileBase file)
        {
            return file.ContentType.Equals("image/jpeg") ||
                   file.ContentType.Equals("image/png");
        }

        private static void SavePhotoInFolder(HttpPostedFileBase file, string pathDisc, string filename, int fW, int fH)
        {
            CreateDirectory(pathDisc);
            if (Directory.Exists(pathDisc))
            {
                ImageHelper.BuildImage(file, pathDisc + '/', filename, fW, fH);
            }
        }

        private ViewDataUploadFileResult BuildUploadFileResult(HttpPostedFileBase file, string fullPath, string thumbnailUrl)
        {
            var st = new ViewDataUploadFileResult
            {
                url = fullPath,
                size = file.ContentLength,
                type = file.ContentType,
                name = file.FileName,
                Title = file.FileName,
                SavedFileName = file.FileName,
                FullPath = fullPath,
                deleteUrl = fullPath,
                thumbnailUrl = thumbnailUrl
            };
            return st;
        }
    }
}